package com.binguo.api.controller;


import com.binguo.api.form.*;
import com.binguo.api.result.Result;
import com.binguo.api.result.ResultGenerator;
import com.binguo.api.service.*;
import com.binguo.api.transfer.OrderFormTransfer;
import com.binguo.common.exception.ServiceException;
import com.binguo.common.util.ImageBase64Util;
import com.binguo.common.util.JsonUtil;
import com.binguo.model.api.dto.OrderDTO;
import com.binguo.model.api.dto.OrderItemDTO;
import com.binguo.model.api.vo.OrderVO;
import com.binguo.model.api.vo.ShangMiOrderVO;
import com.binguo.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;


/**
 * Created by haibang on 18/5/7.
 */
@Api(tags = "收银端: 订单")
@RestController
@RequestMapping
public class OrderController {

    private static Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Autowired
    OrderService orderService;
    @Autowired
    ApiOrderService apiOrderService;
    @Autowired
    OrderFormTransfer orderFormTransfer;
    @Autowired
    AliPayService aliPayService;
    @Autowired
    WXPayService wxPayService;
    @Resource
    RedisLockService redisLockService;
    @Autowired
    CustomerService customerService;
    @Autowired
    QrCodePayQCGService qrCodePayQCGService;
    @Autowired
    ProductService productService;
    @Autowired
    YpCardService ypCardService;
    /**
     * 营养数据同步服务
     */
    @Resource
    private NutrientsSyncService nutrientsSyncService;

    private String ipAddress;

    public OrderController(){
        this.ipAddress = System.getenv().get("ipAddress");
    }


    @PostMapping(value = "/api/order/create", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建预订单", notes = "通过OrderForm")
    public Result create(@RequestBody @Valid OrderForm form,
                         HttpServletRequest request)throws Exception {
        form.validate(form.getItems());

        String key = form.getSerialNumber() + form.getPayType().getCode();

        String uuid = UUID.randomUUID().toString();
        boolean lock = redisLockService.setLockOrder(key, 10000, uuid);
//        boolean lock = true;
//        boolean lock = redisLockService.setLock(key, 10000, uuid);

        OrderVO vo = null;
        if (lock) {
            try {
                vo = apiOrderService.create(orderFormTransfer.toOrderDTO(form), getIpAddr(request));
//                redisLockService.releaseLock(key, uuid);
            } catch (Exception e) {
                redisLockService.releaseLock(key, uuid);
                throw e;
            }
            if (vo != null) {
                nutrientsSyncService.nutrientsSyncByVO(vo);
            }
        } else {
            throw new ServiceException("订单重复");
        }
        logger.info("order response=" + JsonUtil.toJson(vo));
        return ResultGenerator.genSuccessResult(vo);
    }


    @PostMapping(value = "/api/order/uploadOrderImg", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "保存图片", notes = "通过OrderForm")
    public Result dingDanCreate(@RequestBody @Valid UploadImgForm form,
                                HttpServletRequest request)throws Exception {

        StringBuffer outputFilepathStringBuffer = new StringBuffer("/usr/local/nginx/html/images/order/")
                .append(form.getShopId());

        /*StringBuffer outputFilepathStringBuffer = new StringBuffer("C:/Program Files (x86)/apache-tomcat-8.5.47/webapps/ROOT/order/")
                        .append(form.getShopId());*/

        File dirOutput = new File(outputFilepathStringBuffer.toString());
        if (!dirOutput.exists()) {
            dirOutput.mkdir();
        }
        String newFileName = outputFilepathStringBuffer.append("/").append(form.getSerialNumber()).append(".png").toString();

        String httpFileName = new StringBuffer("http://")
                .append(ipAddress)
                .append(":8019/images/order/")
                .append(form.getShopId()).append("/").append(form.getSerialNumber()).append(".png").toString();

        /*String httpFileName = new StringBuffer("http://")
                        .append("123.206.224.209")
                        .append(":8080/")
                        .append("order/")
                        .append(form.getShopId()).append("/").append(form.getSerialNumber()).append(".png").toString();*/


        ImageBase64Util.base64StringToImage(form.getOrderIMG64(), newFileName);
        orderService.saveOrderUrl(form.getSerialNumber(),form.getShopId(), httpFileName);
        return ResultGenerator.genSuccessResult("sucess");
    }

    @PostMapping(value = "/api/order/createShangMi", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "创建预订单", notes = "通过OrderForm")
    public Result createShangMi(@RequestBody @Valid ShangMiForm form,
                                HttpServletRequest request)throws Exception {
        String serialNumber = System.currentTimeMillis()+"";
        String key = serialNumber;

        logger.info("order shangmi=" + JsonUtil.toJson(form));

        String uuid = UUID.randomUUID().toString();
        boolean lock = redisLockService.setLockOrder(key, 10000, uuid);
        OrderVO vo = null;
        if (lock) {
            try {
                 OrderDTO orderDTO = new OrderDTO();
                 if (form.getOrderType() != null){
                     orderDTO.setOrderNo(serialNumber+"SDB");
                 }else {
                     orderDTO.setOrderNo(serialNumber+"SM");
                 }
                 orderDTO.setSerialNumber(serialNumber);
                 orderDTO.setAuthCode(form.getAuthCode());
                 orderDTO.setShopId(form.getShopID());
                 orderDTO.setCardNo(form.getCardNo());
                 orderDTO.setCashierDeskId(form.getCashierDeskID());
                 orderDTO.setOpenId("");
                 orderDTO.setPayType(form.getPayType());
                 orderDTO.setCustomerId(form.getCustomerID());
                 orderDTO.setCustomerPhone(form.getCustomerPhone());
                 orderDTO.setCustomerName(form.getCustomerName());
                 orderDTO.setTotalFee(form.getAccountBalance());
                 orderDTO.setRealFee(form.getAccountBalance());
                 orderDTO.setTotalQuantity(1);
                 List<OrderItemDTO> orderItemList = new ArrayList<>();
                 OrderItemDTO orderItem = new OrderItemDTO();
                 orderItem.setPrice(1L);
                 orderItem.setQuantity(1);
                 orderItem.setProductId(5097);
                 orderItemList.add(orderItem);
                 orderDTO.setItems(orderItemList);

                vo = apiOrderService.create(orderDTO, getIpAddr(request));
            } catch (Exception e) {
                redisLockService.releaseLock(key, uuid);
                throw e;
            }
            if (vo != null) {
                nutrientsSyncService.nutrientsSyncByVO(vo);
            }
        } else {
            throw new ServiceException("订单重复");
        }
        logger.info("order response=" + JsonUtil.toJson(vo));
        return ResultGenerator.genSuccessResult(vo);
    }

    @PostMapping(value = "/api/order/saveIntranetOrder", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "保存内网订单信息", notes = "通过OrderRefundForm")
    public Result saveIntranetOrder(@RequestBody @Valid IntranetOrderListForm form) {

        List<IntranetOrderForm> intranetOrderFormList = form.getIntranetOrderVOList();

        apiOrderService.saveIntranetOrder(intranetOrderFormList,ipAddress);

        return ResultGenerator.genSuccessResult();
    }

    @PostMapping(value = "/api/order/saveIntranetOrderImg", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "保存内网订单图片", notes = "通过OrderRefundForm")
    public Result saveIntranetOrderImg(@RequestBody @Valid IntranetOrderImgListForm form) {

        List<IntranetOrderImgForm> intranetOrderImgFormList = form.getIntranetOrderImgFormList();

        apiOrderService.updateIntranetOrderImg(intranetOrderImgFormList);

        return ResultGenerator.genSuccessResult();
    }

    @PostMapping(value = "/api/order/getShangMiOrder", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取商米订单信息", notes = "通过OrderRefundForm")
    public Result getShangMiOrder(@RequestBody @Valid FindShangMiOrderForm form) {
        List<ShangMiOrderVO> shangMiOrderVOList = apiOrderService.getShangMiOrder(form.getLimit(),form.getCashierDeskID());
        return ResultGenerator.genSuccessResult(shangMiOrderVOList);
    }

    @GetMapping(value = "/api/order/getShangMiOrder/{caskierDeskId}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取商米订单信息", notes = "通过OrderRefundForm")
    public Result getShangMiOrderByCaskierDesk(@PathVariable Integer caskierDeskId) {
        logger.info("获取商米订单信息:caskierDeskId:{}", caskierDeskId);
        return ResultGenerator.genSuccessResult(orderService.getSMOrderByDeskId(caskierDeskId));
    }

    @PostMapping(value = "/api/order/refund", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "订单退款", notes = "通过OrderRefundForm")
    public Result refund(@RequestBody @Valid OrderRefundForm form) {
        OrderVO vo = apiOrderService.refund(form.getOrderNo(), form.getRefundFee());
        return ResultGenerator.genSuccessResult(vo);
    }


    @GetMapping(value = "/api/order/serial/{serialNumber}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取流水号对应订单列表", notes = "通过serialNumber")
    public Result getSerialOrder(@PathVariable String serialNumber) {
        List<OrderVO> vos = orderService.findOrdersBySerialNumber(serialNumber);
        return ResultGenerator.genSuccessResult(vos);
    }


    @GetMapping(value = "/api/order/{orderNo}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取单个订单", notes = "通过orderNo")
    public Result getOrder(@PathVariable String orderNo) {
        OrderVO vo = orderService.findOneByOrderNo(orderNo);
        return ResultGenerator.genSuccessResult(vo);
    }



    @GetMapping(value = "/api/order/history", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取历史订单", notes = "通过商户id,收银台id,最后一条订单号")
    public Result getOrders(@ApiParam("商户id 假数据id:2") @RequestParam @NotNull Integer shopId,
                         @ApiParam("收银台id 假数据id:5") @RequestParam @NotNull Integer cashierDeskId,
                         @ApiParam("可选 订单状态(1:已付款,2:已退款, 默认全部)") @RequestParam  Optional<Integer> orderStatus,
                         @ApiParam("可选 最后一条订单号 默认最新20条") @RequestParam Optional<String> lastOrderNo) {
        List<OrderVO> list = orderService.findOrders(shopId, cashierDeskId, orderStatus, lastOrderNo);
        return ResultGenerator.genSuccessResult(list);
    }



    @PostMapping(value = "/api/alipay/notity", produces = APPLICATION_XML_VALUE)
    public void aliPaynotity(HttpServletRequest request) {
         aliPayService.notify(request);
    }


    @PostMapping(value = "/api/wxpay/refund/notity", produces = APPLICATION_XML_VALUE)
    public String refundNotity(HttpServletRequest request) {
        return wxPayService.reFundNotify(request);
    }

    /*@GetMapping(value = "/api/order/getSMOrders", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取历史订单", notes = "通过商户id,收银台id,最后一条订单号")
    public Result getSMOrders(@ApiParam("收银台id") @RequestParam @NotNull Integer cashierDeskId) {
        return ResultGenerator.genSuccessResult(orderService.getSMOrderByDeskId(cashierDeskId));
    }*/



    @PostMapping(value = "/api/wxpay/notity", produces = APPLICATION_XML_VALUE)
    public String notity(HttpServletRequest request) {
        return wxPayService.notify(request);
    }

    @PostMapping(value = "/api/order/syncNutrients/{orderNo}", produces = APPLICATION_JSON_VALUE)
    @ApiOperation(value = "订单生成营养数据", notes = "通过orderNo")
    public Result syncNutrients(@PathVariable String orderNo) {
        nutrientsSyncService.nutrientsSyncByOrderNo(orderNo);
        return ResultGenerator.genSuccessResult();
    }

   /* @PostMapping("/api/product/getOrderProductPrice")
    public OrderProductPriceBackFrom getProductPrice(@RequestBody JSONObject jsonParam){
        return apiOrderService.getOrderPrice(jsonParam);
    }*/

   /*@GetMapping(value = "/api/order/getOrderCount", produces = APPLICATION_JSON_VALUE)
   public Result getOrderCount(){
       orderService.getOrderCount();
       return ResultGenerator.genSuccessResult("");
   }*/

    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

}
